﻿// utils/broadcast.ts

interface BroadcastMessage<T = any> {
    type: string;
    payload: T;
    timestamp: number;
}

class BroadcastManager {
    private channel: BroadcastChannel;
    private listeners: Map<string, Set<(data: any) => void>>;

    constructor(channelName: string) {
        this.channel = new BroadcastChannel(channelName);
        this.listeners = new Map();
        this.init();
    }

    /**
     * 初始化监听器
     */
    private init(): void {
        this.channel.addEventListener('message', (event: MessageEvent<BroadcastMessage>) => {
            const { type, payload } = event.data;
            const handlers = this.listeners.get(type);

            if (handlers) {
                handlers.forEach(handler => handler(payload));
            }
        });
    }

    /**
     * 发送消息
     * @param type 消息类型
     * @param payload 消息负载
     */
    public send<T>(type: string, payload: T): void {
        const message: BroadcastMessage<T> = {
            type,
            payload,
            timestamp: Date.now(),
        };

        this.channel.postMessage(message);
    }

    /**
     * 监听指定类型的消息
     * @param type 消息类型
     * @param callback 回调函数
     */
    public on<T>(type: string, callback: (data: T) => void): void {
        if (!this.listeners.has(type)) {
            this.listeners.set(type, new Set());
        }

        this.listeners.get(type)?.add(callback);
    }

    /**
     * 移除指定类型的消息监听
     * @param type 消息类型
     * @param callback 回调函数
     */
    public off<T>(type: string, callback: (data: T) => void): void {
        const handlers = this.listeners.get(type);
        if (handlers) {
            handlers.delete(callback);
        }
    }

    /**
     * 监听一次指定类型的消息
     * @param type 消息类型
     * @param callback 回调函数
     */
    public once<T>(type: string, callback: (data: T) => void): void {
        const onceCallback = (data: T) => {
            callback(data);
            this.off(type, onceCallback);
        };

        this.on(type, onceCallback);
    }

    /**
     * 关闭频道连接
     */
    public close(): void {
        this.channel.close();
        this.listeners.clear();
    }
}

// 创建默认实例
export const broadcast = new BroadcastManager('app_broadcast_channel');

// 导出类以便创建多个实例
export default BroadcastManager;
